﻿using IoTSocket.Core;
using JunionRobotTaskManager.Extensions;
using JunionRobotTaskManager.Models;
using JunionRobotTaskManager.Repository;
using LazyCache;
using Microsoft.Extensions.Options;
using Redbus.Interfaces;

namespace JunionRobotTaskManager.Services
{
    public class ParkService
    {
        private readonly IServiceProvider serviceProvider;
        private readonly IAppCache _cache;
        private readonly object _lock = new object();
        private readonly ILogger<ParkService> _logger;
        private readonly IConfiguration configuration;
        private readonly IOptionsMonitor<SystemInfo> _optionsMonitor;

        public ParkService(IServiceProvider serviceProvider, IAppCache cache, ILogger<ParkService> logger, IConfiguration configuration, IOptionsMonitor<SystemInfo> optionsMonitor)
        {
            this.serviceProvider = serviceProvider;
            _cache = cache;
            _logger = logger;
            this.configuration = configuration;
            _optionsMonitor = optionsMonitor;
        }

        public void DealPark(Robot robot)
        {
            if (_optionsMonitor.CurrentValue.IsParkControl)
            {
                lock (_lock)
                {
                    if (_cache.TryGetValue("Parks", out List<Park> parks))
                    {
                        var idleParks = parks.FindAll(x => !x.IsOccupied && ((_optionsMonitor.CurrentValue.IsRegionCheck && x.Region == robot.Region) || !_optionsMonitor.CurrentValue.IsRegionCheck));
                        if (idleParks.Count > 0)
                        {
                            Park park = null;
                            park = idleParks.OrderByDescending(x => x.Floor == robot.Floor).ThenBy(x => Math.Sqrt(Math.Pow(x.XPosition - robot.PosX, 2) + Math.Pow(x.YPosition - robot.PosY, 2))).First();
                            //var dic = configuration.GetSection("Parks")[robot.Id];   //park点是否要与agv绑定？？
                            //var park = idleParks.Find(x => x.Id == dic);
                            var route = robot.Floor == park.Floor ? $"{park.Id}" : $"{robot.Floor}F-{park.Floor}F_{park.Id}";
                            if (robot.ExcutePath(route, DateTime.Now.ToString("MMddHHmmss")))
                            {
                                _logger.LogInformation("The robot {0} occupy the park :{1}", robot.IP, park.Id);
                                park.IsOccupied = true;
                                park.RobotId = robot.Id;
                                using var scope = serviceProvider.CreateScope();
                                var parkRepository = scope.ServiceProvider.GetService<IParkRepository>();
                                parkRepository.UpdateEntity(park);
                            }
                        }
                    }
                }
            }
        }
    }
}
